//
// Created by work on 24-11-8.
//

#include "CModbusMap.h"

CModbusMap::CModbusMap(std::string mapId, std::string devname) : m_mapId(mapId),m_devName(devname){
    loadYxUnits();
    loadYcUnits();
    loadYkUnits();
    loadParameterUnits();
}

SDataUnit CModbusMap::getCurrCallUnit() {
    if(!m_sigList.size())
        exit(-1);

    SDataUnit unit = m_sigList[m_pos];
    ++ m_pos;
    if(m_pos ==  m_sigList.size()) {
        m_pos = 0;
    }
    return unit;
}

bool CModbusMap::loadYxUnits() {
    GET_DB_HANDLE(iotplat::CConfigs::EDateBase::EPlat);
    std::ostringstream sql;
    sql << "SELECT name,reg_type,address,is_bit,bit_offset,is_filter,flag";
    sql << " FROM " << "t_modbus_map_yx";
    sql << " WHERE map_id='" << m_mapId << "';";

    std::shared_ptr<CResultSet> res(db->query(sql.str().c_str()));

    if(!res){
        OUTPUT_WARNING_INFO(std::string("db exec failed: " + sql.str()));
        return false;
    }

    while(res->next()) {
        SDataUnit unit;
        unit.sigtype = SDataUnit::Yx;
        unit.name = res->asString(0);
        unit.regtype = static_cast<SDataUnit::RegisterType>(res->asInt(1));
        unit.saddress = res->asInt(2);
        if(unit.regtype == SDataUnit::HoldingRegisters || unit.regtype == SDataUnit::InputRegisters) {
            if(res->asBool(3)) {
                unit.isbit = true;
                unit.bitoffest = res->asInt(4);
            }
        }
        unit.isFilterCall = res->asBool(5);
        m_sigList.push_back(unit);
    }
    return true;
}

bool CModbusMap::loadYcUnits() {
    GET_DB_HANDLE(iotplat::CConfigs::EDateBase::EPlat);
    std::ostringstream sql;
    sql << "SELECT name,reg_type,address,datalen,datatype,flag";
    sql << " FROM " << "t_modbus_map_yc";
    sql << " WHERE map_id='" << m_mapId << "';";

    std::shared_ptr<CResultSet> res(db->query(sql.str().c_str()));
    if(!res){
        OUTPUT_WARNING_INFO(std::string("db exec failed: " + sql.str()));
        return false;
    }

    while(res->next()) {
        SDataUnit unit;
        unit.sigtype = SDataUnit::Yc;
        unit.name = res->asString(0);
        unit.regtype = static_cast<SDataUnit::RegisterType>(res->asInt(1));
        unit.saddress = res->asInt(2);
        unit.isFilterCall = res->asBool(5);
        m_sigList.push_back(unit);
    }
    return true;
}

bool CModbusMap::loadYkUnits() {
    GET_DB_HANDLE(iotplat::CConfigs::EDateBase::EPlat);
    std::ostringstream sql;
    sql << "SELECT name,reg_type,address,is_bit,bit_offset,is_filter,flag";
    sql << " FROM " << "t_modbus_map_yk";
    sql << " WHERE map_id='" << m_mapId << "';";

    std::shared_ptr<CResultSet> res(db->query(sql.str().c_str()));

    if(!res){
        OUTPUT_WARNING_INFO(std::string("db exec failed: " + sql.str()));
        return false;
    }

    while(res->next()) {
        SDataUnit unit;
        unit.sigtype = SDataUnit::Yk;
        unit.name = res->asString(0);
        unit.regtype = static_cast<SDataUnit::RegisterType>(res->asInt(1));
        unit.saddress = res->asInt(2);
        if(unit.regtype == SDataUnit::HoldingRegisters || unit.regtype == SDataUnit::InputRegisters) {
            if(res->asBool(3)) {
                unit.isbit = true;
                unit.bitoffest = res->asInt(4);
            }
        }
        unit.isFilterCall = res->asBool(5);
        m_sigList.push_back(unit);
    }
    return true;
}

bool CModbusMap::loadParameterUnits() {
    GET_DB_HANDLE(iotplat::CConfigs::EDateBase::EPlat);
    std::ostringstream sql;
    sql << "SELECT name,reg_type,address,datalen,datatype,flag";
    sql << " FROM " << "t_modbus_map_parameter";
    sql << " WHERE map_id='" << m_mapId << "';";

    std::shared_ptr<CResultSet> res(db->query(sql.str().c_str()));
    if(!res){
        OUTPUT_WARNING_INFO(std::string("db exec failed: " + sql.str()));
        return false;
    }

    while(res->next()) {
        SDataUnit unit;
        unit.sigtype = SDataUnit::Parameter;
        unit.name = res->asString(0);
        unit.regtype = static_cast<SDataUnit::RegisterType>(res->asInt(1));
        unit.saddress = res->asInt(2);
        unit.isFilterCall = res->asBool(5);
        m_sigList.push_back(unit);
    }
    return true;
}
